﻿using AccessibilityTools.DB;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TianYi.Bll;
using log4net;
using Sunny.UI;
using System.IO;
using TianYi.Helper;

namespace TianYi
{
    public partial class FrmMain : Form
    {
        #region 声明变量
        ErrorInfoLogic ErrorInfoLogic = new ErrorInfoLogic();
        PressureValueInfoLogic PressureValueInfoLogic = new PressureValueInfoLogic();
        ProductionDetalisLogic ProductionDetalisLogic = new ProductionDetalisLogic();
        PlcItemAddress plcItemAddresses = new PlcItemAddress();
        PlcController plc;
        bool _Flag1;
        private UILineChart optionChar;
        private UILineOption option = new UILineOption();
        public delegate void AddLogHandler(string source, string log);
        public event AddLogHandler AddLogEventHandler;
        #endregion

        public FrmMain()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            this.Tag = this.Width.ToString() + "," + this.Height.ToString();
            this.SizeChanged += new EventHandler(Form1_SizeChanged);
            #region 绑定委托 主线程 plc模块  业务模块等绑定
            AddLogEventHandler += AddLog;
            PlcController.AddOpcLogEventHandler += AddLog;
            TaskAction.AddLogEventHandler += AddLog;
            #endregion

            ChangeDatagridviewStyle_ErrorTable(dgv_ProductionData);//初始化显示表格
            dtStartTime.Value = DateTime.Now; //初始化表格时间
            dtEndTime.Value = DateTime.Now;


        }

        #region 解析json文件PLC地址
        private PlcItemAddress PLCConnectConfig()
        {
            string filePath = System.Windows.Forms.Application.StartupPath + "\\" + "config" + "\\" + "Plcsignal.json";
            string text = File.ReadAllText(filePath);
            JsonHelper configHelper = new JsonHelper();
            PlcItemAddress data = configHelper.GetJsonDeserialize<PlcItemAddress>(filePath);
            return data;
        }
        #endregion

        /// <summary>
        /// 初始化Load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_Load(object sender, EventArgs e)
        {
            //开启plc
            AddLogEventHandler("初始化", "初始化参数");
            LogHelper.WriteInfo("plc连接成功!");
            log4net.Config.XmlConfigurator.Configure();//初始化
            plcItemAddresses = PLCConnectConfig();//plc地址参数初始化
            Task.Factory.StartNew(() =>
            {
                plc = new PlcController(plcItemAddresses.Op10Connection.PlcType, plcItemAddresses.Op10Connection.IP,
                    Convert.ToInt16(plcItemAddresses.Op10Connection.Rack), Convert.ToInt16(plcItemAddresses.Op10Connection.Slot));
                _Flag1 = plc.Connect();
                if (_Flag1)
                {
                    TaskAction taskplc = new TaskAction();
                    //开启心跳plc为plc10站
                    taskplc.StartAction(plc);
                    this.Invoke(new Action(() =>
                    {
                        AddLogEventHandler("PLC", "PLC连接成功!");

                    }));

                    LogHelper.WriteInfo("plc连接成功!");
                }
                else
                {
                    this.Invoke(new Action(() =>
                    {
                        AddLogEventHandler("PLC", "PLC连接失败!");

                    }));

                    LogHelper.WriteError("plc连接失败!");
                }
            });
            //写入数据库数据在model里面
            ErrorInfo errorProtectionIntance = new ErrorInfo()
            {
                ProductTypes = "123",
                ProductStatus = 1,
                Error_Info = "启动失败",
                CreationTime = DateTime.Now

            };
            // ErrorInfoLogic.Add(errorProtectionIntance);
            PressureValueInfo pressureValueInstance = new PressureValueInfo()
            {
                PressureValue = "12.45,34.2,45,22.22,56.3,73.2,23.4,45.4,12.45,34.2,45,22.22,56.3,73.2,23.4,45.4",
                CreationTime = DateTime.Now
            };
            //PressureValueInfoLogic.Add(pressureValueInstance);

            ProductionDetailsInfo productionDetailsInstance = new ProductionDetailsInfo()
            {
                ProductTypes = "123",
                Production_Length = 12.22,
                Large_Outer_Diameter = 23.55,
                Small_Outer_Diameter = 6.18,
                Bottom_Cover_Value = 45.22,
                Production_Height = 46.2,
                Displacement_Value = 22.33,
                Pressure_Limmit_Value = 22.4,
                CreationTime = DateTime.Now

            };
            // int count = ProductionDetalisLogic.Add(productionDetailsInstance);
            LoadProductTypesToComboBox();
        }

        #region 改变窗体控件的大小自适应
        private void Form1_SizeChanged(object sender, EventArgs e)
        {

            string[] tmp = ((Form)sender).Tag.ToString().Split(',');
            //比例因子
            float width = (float)((Form)sender).Width / (float)Convert.ToInt16(tmp[0]);
            float heigth = (float)((Form)sender).Height / (float)Convert.ToInt16(tmp[1]);
            //保存变化后的大小，下一次再根据这个求比例因子
            ((Form)sender).Tag = ((Form)sender).Width.ToString() + "," + ((Form)sender).Height;
            //根据比例因子，重绘所有控件
            foreach (Control control in ((Form)sender).Controls)
            {
                control.Scale(new SizeF(width, heigth));
            }
            SetChartLineStyle();
        }
        #endregion

        private void timer1_Tick(object sender, EventArgs e)
        {
            lbl_time.Text = DateTime.Now.ToString("G");
        }
        /// <summary>
        /// 增加日志
        /// </summary>
        /// <param name="source"></param>
        /// <param name="log"></param>
        private void AddLog(string source, string log)
        {
            try
            {
                this.BeginInvoke(new Action(() =>
                {
                    string timeStr = DateTime.Now.ToString("HH:mm:ss:fff");
                    string content = $"{timeStr}:[{source}]{log}";
                    txtLog.AppendText(content + "\r\n");
                    switch (source)
                    {
                        case "总站工作结束":
                            //查询生产表最新一条数据
                            ProductionDetailsInfo ProductionInstance = ProductionDetalisLogic.GetListByTime();
                            PressureValueInfo pressureValueInfoInstance = PressureValueInfoLogic.GetListByTime();
                            textBox1.Text = ProductionInstance.ProductTypes; //sn
                            textBox2.Text = ProductionInstance.Production_Length.ToString();//长度
                            textBox3.Text = ProductionInstance.Large_Outer_Diameter.ToString();//大径值
                            textBox4.Text = ProductionInstance.Small_Outer_Diameter.ToString();//小径值
                            textBox5.Text = ProductionInstance.Bottom_Cover_Value.ToString();//底盖外径
                            textBox6.Text = ProductionInstance.Production_Height.ToString();//高度
                            textBox7.Text = ProductionInstance.Displacement_Value.ToString();//位移值
                            textBox8.Text = ProductionInstance.Pressure_Limmit_Value.ToString();//压力极限值
                            textBox9.Text = ProductionInstance.CreationTime.ToString();//创建时间
                            textBox10.Text = ProductionInstance.Qr_Code.ToString();//二维码
                            break;
                        case "第一站工作结束":
                            ProductionDetailsInfo ProductionInstance1 = ProductionDetalisLogic.GetListByTime();
                            textBox1.Text = ProductionInstance1.ProductTypes; //sn
                            textBox2.Text = ProductionInstance1.Production_Length.ToString();//长度
                            textBox3.Text = ProductionInstance1.Large_Outer_Diameter.ToString();//大径值
                            textBox4.Text = ProductionInstance1.Small_Outer_Diameter.ToString();//小径值
                            textBox5.Text = "";
                            textBox6.Text = "";
                            textBox7.Text = "";
                            textBox8.Text = "";
                            textBox9.Text = "";
                            textBox10.Text = "";
                            break;
                        case "第二站工作结束":
                            ProductionDetailsInfo ProductionInstance2 = ProductionDetalisLogic.GetListByTime();
                            PressureValueInfo pressureValueInfoInstance2 = PressureValueInfoLogic.GetListByTime();
                            textBox1.Text = "";
                            textBox2.Text = "";
                            textBox3.Text = "";
                            textBox4.Text = "";
                            textBox5.Text = ProductionInstance2.Bottom_Cover_Value.ToString();//底盖外径
                            textBox6.Text = ProductionInstance2.Production_Height.ToString();//高度
                            textBox7.Text = ProductionInstance2.Displacement_Value.ToString();//位移值
                            textBox8.Text = ProductionInstance2.Pressure_Limmit_Value.ToString();//压力极限值
                            textBox9.Text = ProductionInstance2.CreationTime.ToString();//创建时间
                            textBox10.Text = ProductionInstance2.Qr_Code.ToString();//二维码
                            break;
                    }
                }));
                // _runlogBll.AddLog(source, log);
            }
            catch (Exception ex)
            {

                throw ex;
            }

        }

        #region 改变Datagridview样式
        /// <summary>
        /// 改变Datagridview样式
        /// </summary>
        /// <param name="dgv"></param>
        private void ChangeDatagridviewStyle_ErrorTable(DataGridView dgv)
        {
            dgv_ProductionData.Columns.Clear();
            dgv_ProductionData.Refresh();
            dgv.DefaultCellStyle.Font = new Font("宋体", 15);

            dgv_ProductionData.Columns.Add("Column1", "产品ID");
            dgv_ProductionData.Columns.Add("Column2", "产品种类");
            dgv_ProductionData.Columns.Add("Column3", "产品状态");
            dgv_ProductionData.Columns.Add("Column4", "报错信息");
            dgv_ProductionData.Columns.Add("Column5", "删除标志位");
            dgv_ProductionData.Columns.Add("Column6", "创建时间");
            for (int i = 0; i < dgv_ProductionData.Columns.Count; i++)
            {
                dgv_ProductionData.Columns[i].Width = 150;
            }
        }
        private void ChangeDatagridviewStyle_PressureTable(DataGridView dgv)
        {
            dgv_ProductionData.Columns.Clear();
            dgv_ProductionData.Refresh();
            dgv.DefaultCellStyle.Font = new Font("宋体", 15);

            dgv_ProductionData.Columns.Add("Column1", "产品ID");
            dgv_ProductionData.Columns.Add("Column2", "压力值");
            dgv_ProductionData.Columns.Add("Column4", "删除标志位");
            dgv_ProductionData.Columns.Add("Column5", "创建时间");

            for (int i = 0; i < dgv_ProductionData.Columns.Count; i++)
            {
                dgv_ProductionData.Columns[i].Width = 200;
            }
        }
        private void ChangeDatagridviewStyle_ProductionTable(DataGridView dgv)
        {
            dgv_ProductionData.Columns.Clear();
            dgv_ProductionData.Refresh();
            dgv.DefaultCellStyle.Font = new Font("宋体", 15);

            dgv_ProductionData.Columns.Add("Column1", "产品ID");
            dgv_ProductionData.Columns.Add("Column2", "产品类型");
            dgv_ProductionData.Columns.Add("Column3", "产品长度");
            dgv_ProductionData.Columns.Add("Column4", "产品大外径");
            dgv_ProductionData.Columns.Add("Column5", "产品小外径");
            dgv_ProductionData.Columns.Add("Column6", "底盖外径");
            dgv_ProductionData.Columns.Add("Column7", "产品高度");
            dgv_ProductionData.Columns.Add("Column8", "产品位移值");
            dgv_ProductionData.Columns.Add("Column9", "压力极限值");
            dgv_ProductionData.Columns.Add("Column10", "删除标志位");
            dgv_ProductionData.Columns.Add("Column11", "创建时间");
            dgv_ProductionData.Columns.Add("Column12", "二维码");

            for (int i = 0; i < dgv_ProductionData.Columns.Count; i++)
            {
                dgv_ProductionData.Columns[i].Width = 200;
            }
        }
        #endregion

        #region 产品查询
        /// <summary>
        /// 产品查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Productquery_Click(object sender, EventArgs e)
        {

            if (combox_select.Text == "报警表")
            {
                try
                {
                    Task.Run(() =>
                    {
                        DateTime startime = dtStartTime.Value;
                        DateTime endtime = dtEndTime.Value;
                        this.Invoke(new Action(() =>
                        {
                            dgv_ProductionData.Rows.Clear();
                            dgv_ProductionData.Refresh();
                        }));


                        List<ErrorInfo> Errorinstance = ErrorInfoLogic.SelectDetailsByDatetime(startime, endtime);
                        LogHelper.WriteInfo("报警数据库查询申请");
                        if (Errorinstance != null)
                        {
                            foreach (var item in Errorinstance)
                            {
                                string[] items = new string[] { item.Id.ToString(), item.ProductTypes, item.ProductStatus.ToString(), item.Error_Info, item.IsDeleted.ToString(), item.CreationTime.ToString("G") };
                                this.Invoke(new Action(() =>
                                {
                                    dgv_ProductionData.Rows.Add(items);
                                    dgv_ProductionData.Refresh();
                                }));
                            }

                            LogHelper.WriteInfo("报警数据库查询完成");
                        }
                        else
                        {
                            LogHelper.WriteInfo("未查询到报警数据库");
                        }
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show("数据追溯", $"用户按下查询按钮，但发生了一个异常{ex.Message}");
                }

            }
            else if (combox_select.Text == "压力值表")
            {
                try
                {
                    Task.Run(() =>
                    {
                        DateTime startime = dtStartTime.Value;
                        DateTime endtime = dtEndTime.Value;
                        this.Invoke(new Action(() =>
                        {
                            dgv_ProductionData.Rows.Clear();
                            dgv_ProductionData.Refresh();
                        }));

                        List<PressureValueInfo> Pressureinstance = PressureValueInfoLogic.SelectDetailsByDatetime(startime, endtime);
                        LogHelper.WriteInfo("压力值数据库查询申请");
                        if (Pressureinstance != null)
                        {
                            foreach (var item in Pressureinstance)
                            {
                                string[] items = new string[] { item.Id.ToString(), item.PressureValue.ToString(), item.IsDeleted.ToString(), item.CreationTime.ToString("G") };
                                this.Invoke(new Action(() =>
                                {
                                    dgv_ProductionData.Rows.Add(items);
                                    dgv_ProductionData.Refresh();
                                }));
                            }

                            LogHelper.WriteInfo("压力值数据库查询完成");
                        }
                        else
                        {
                            LogHelper.WriteInfo("未查询到压力值数据库");
                        }
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show("数据追溯", $"用户按下查询按钮，但发生了一个异常{ex.Message}");
                }
            }
            else if (combox_select.Text == "生产信息表")
            {
                try
                {
                    Task.Run(() =>
                    {
                        DateTime startime = dtStartTime.Value;
                        DateTime endtime = dtEndTime.Value;
                        //获取用户输入的产品码
                        string qrCode = txtProductQrCode.Text.Trim();
                        //获取下拉框所选产品
                        string selectedProductType = combox_ProductTypes.SelectedItem?.ToString();
                        this.Invoke(new Action(() =>
                        {
                            ChangeDatagridviewStyle_ProductionTable(dgv_ProductionData);
                            dgv_ProductionData.Rows.Clear();
                            dgv_ProductionData.Refresh();
                        }));

                        List<ProductionDetailsInfo> Productioninstance;
                        LogHelper.WriteInfo("生产数据库查询申请");

                        if (!string.IsNullOrEmpty(qrCode))
                        {
                            Productioninstance = ProductionDetalisLogic.SelectDetailsByQrCode(qrCode);
                        }
                        else
                        {
                            if (selectedProductType == null || selectedProductType == "全部")
                            {
                                Productioninstance = ProductionDetalisLogic.SelectDetailsByDatetime(startime, endtime);
                            }
                            else
                            {
                                Productioninstance = ProductionDetalisLogic.SelectDetailsByDatetimeAndType(startime, endtime, selectedProductType);
                            }
                        }

                        if (Productioninstance != null)
                        {
                            foreach (var item in Productioninstance)
                            {
                                string[] items = new string[] { item.Id.ToString(), item.ProductTypes, item.Production_Length.ToString(), item.Large_Outer_Diameter.ToString(), item.Small_Outer_Diameter.ToString(), item.Bottom_Cover_Value.ToString(), item.Production_Height.ToString(), item.Displacement_Value.ToString(), item.Pressure_Limmit_Value.ToString(), item.IsDeleted.ToString(), item.CreationTime.ToString("G"), item.Qr_Code };
                                this.Invoke(new Action(() =>
                                {
                                    dgv_ProductionData.Rows.Add(items);
                                    dgv_ProductionData.Refresh();
                                    //txtProductQrCode.Text = "";
                                }));
                            }

                            LogHelper.WriteInfo("生产数据库查询完成");
                        }
                        else
                        {
                            LogHelper.WriteInfo("生产到压力值数据库");
                        }
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show("数据追溯", $"用户按下查询按钮，但发生了一个异常{ex.Message}");
                }
            }
        }
        #endregion

        ////  初始加载        
        private void LoadPressureData(double[] XAxis, double[] YAxis)
        {
            uiLineChart.Option.Clear(); //清除内容
            optionChar = uiLineChart;
            AddChartData($"压力数据:1", XAxis, YAxis);
            SetChartLineStyle();
        }

        ///// <summary>
        ///// 向图标添加数据
        ///// </summary>
        ///// <param name="name">线条名称</param>
        ///// <param name="arrx">横轴数据</param>
        ///// <param name="arry">纵轴数据</param>
        private void AddChartData(string name, double[] arrx, double[] arry)
        {

            var series = option.AddSeries(new UILineSeries("Line1"));
            for (int i = 0; i < arrx.Length; i++)
            {
                series.Add(arrx[i], arry[i]);
            }
            uiLineChart.Option.AddSeries(series);
        }

        private void SetChartLineStyle()
        {
            uiLineChart.Option.ShowZeroLine = true;
            uiLineChart.Option.ShowZeroValue = true;
            uiLineChart.Option.XAxis.Clear();
            uiLineChart.Option.YAxis.Clear();
            var uiTitle = new UITitle { Text = "压力测试情况", SubText = "压力值曲线" };

            uiLineChart.Option.Title = uiTitle;//设置图表名称
            uiLineChart.Option.XAxis.Name = "数量";//横轴名称
            uiLineChart.Option.YAxis.Name = "压力值";//纵轴名称

            uiLineChart.Option.XAxis.ShowGridLine = true;//横轴网格线
            uiLineChart.Option.YAxis.ShowGridLine = true;//纵轴网格线

            // 设置纵坐标上限红线
            option.GreaterWarningArea = new UILineWarningArea();
            // 设置纵坐标下线黄线
            option.LessWarningArea = new UILineWarningArea();
            option.YAxisScaleLines.Add(new UIScaleLine() { Color = Color.Red, Name = "上限", Value = 55 });
            option.YAxisScaleLines.Add(new UIScaleLine() { Color = Color.Yellow, Name = "下限", Value = 10 });

            //uiLineChart1.Option.XAxisType = UIAxisType.Value;//横轴类型
            //uiLineChart1.Option.XAxis.SetRange(DateTime.Now, DateTime.Now.AddMinutes(10));//设置横轴时间范围
            uiLineChart.Option.XAxisType = UIAxisType.Value;//横轴类型

            uiLineChart.Option.XAxis.SetRange(0, 500);//设置横轴范围（1.类型为时间时需要设置时间范围；2.可通过改属性重置图表显示）
            uiLineChart.Option.YAxis.SetRange(0, 200);//设置横轴范围（1.类型为时间时需要设置时间范围；2.可通过改属性重置图表显示）

            uiLineChart.SetOption(option);
            uiLineChart.Refresh();

        }
        /// <summary>
        /// 选择表改变时候
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void combox_select_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (combox_select.Text == "报警表")
            {
                panel4.Visible = false;
                ChangeDatagridviewStyle_ErrorTable(dgv_ProductionData);
            }
            else if (combox_select.Text == "压力值表")
            {
                panel4.Visible = false;
                ChangeDatagridviewStyle_PressureTable(dgv_ProductionData);
            }
            else if (combox_select.Text == "生产信息表")
            {
                panel4.Visible = true;
                ChangeDatagridviewStyle_ProductionTable(dgv_ProductionData);
            }
        }

        /// <summary>
        /// 双击发生，处理单元格中的数据并加载到数据表中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgv_ProductionData_DoubleClick(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                try
                {
                    //数据获取与处理
                    int count = 0;//数量赋值
                    string currenttext = dgv_ProductionData.CurrentCell.Value.ToString();
                    string[] currenttextArray = currenttext.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);//分割并且排除空值

                    //初始化
                    double[] doubleTextArray = new double[currenttextArray.Length];
                    double[] doubleCountArray = new double[currenttextArray.Length];

                    for (int i = 0; i < currenttextArray.Length; i++)
                    {
                        count++;
                        doubleCountArray[i] = Convert.ToDouble(count - 1);
                    }
                    //数组转换将string转换为double
                    doubleTextArray = Array.ConvertAll<string, double>(currenttextArray, s => double.Parse(s));
                    this.Invoke(new Action(() =>
                    {
                        LoadPressureData(doubleCountArray, doubleTextArray);
                    }));
                }
                catch
                {
                }
            });
        }

        /// <summary>
        /// 加载不同种类到下拉框中
        /// </summary>
        private void LoadProductTypesToComboBox()
        {
            try
            {
                // 从数据库中查询不同的 production_types
                var productTypes = ProductionDetalisLogic.GetDistinctProductTypes();

                // 对查询结果进行排序
                var sortedProductTypes = productTypes.OrderBy(x => x.ToLower()).ToList();

                // 对排序后的结果进行编号
                var numberedProductTypes = new List<string>();
                for (int i = 0; i < sortedProductTypes.Count; i++)
                {
                    numberedProductTypes.Add($"{sortedProductTypes[i]}");
                }

                // 将编号后的结果添加到下拉框中
                combox_ProductTypes.Items.Clear();
                combox_ProductTypes.Items.AddRange(numberedProductTypes.ToArray());
                combox_ProductTypes.Items.Add("全部");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载产品种类时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 关闭程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (plc != null)
            {
                plc.Close();
                this.Dispose();
                this.Close();
            }
        }

    }
}
